package com.studyweb.service.impl;

import com.studyweb.mapper.UserMapper;
import com.studyweb.pojo.entity.User;
import com.studyweb.service.UserService;
import com.studyweb.service.VerificationCodeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 用户服务实现类
 * 
 * @author StudyWeb Team
 * @since 1.0.0
 */
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private VerificationCodeService verificationCodeService;

    private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 用户注册方法
     * 
     * @param user 用户注册信息
     * @return boolean 注册是否成功
     * @throws Exception 注册过程中可能出现的异常
     * @apiNote 会检查用户名、手机号、邮箱的唯一性，并对密码进行BCrypt加密
     */
    @Override
    public boolean register(User user) {
        try {
            // 加密密码
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            
            // 设置默认值
            if (user.getStatus() == null) {
                user.setStatus(1); // 默认启用
            }
            if (user.getUserType() == null) {
                user.setUserType(0); // 默认普通用户
            }
            if (!StringUtils.hasText(user.getNickname())) {
                user.setNickname(user.getUsername()); // 默认昵称为用户名
            }

            int result = userMapper.insert(user);
            if (result > 0) {
                log.info("用户注册成功：{}", user.getUsername());
                return true;
            }
        } catch (Exception e) {
            log.error("用户注册异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 用户登录方法
     * 
     * @param username 用户名（支持用户名、手机号、邮箱登录）
     * @param password 密码（明文）
     * @return User 登录成功返回用户信息（已清除密码），失败返回null
     * @throws Exception 登录过程中可能出现的异常
     * @apiNote 支持多种登录方式，会验证密码并更新最后登录时间
     */
    @Override
    public User login(String username, String password, HttpServletRequest request) {
        try {
            User user = null;
            
            // 尝试通过用户名查找
            user = userMapper.selectByUsername(username);
            
            // 如果用户名未找到，尝试通过手机号查找
            if (user == null && username.matches("^1[3-9]\\d{9}$")) {
                user = userMapper.selectByPhone(username);
            }
            
            // 如果手机号未找到，尝试通过邮箱查找
            if (user == null && username.contains("@")) {
                user = userMapper.selectByEmail(username);
            }

            if (user != null && passwordEncoder.matches(password, user.getPassword())) {
                // 检查用户状态
                if (user.getStatus() == 0) {
                    log.warn("用户登录失败：账户已被禁用 - {}", username);
                    return null;
                }
                
                // 更新最后登录时间
                updateLastLoginTime(user.getUserId());
                
                // 清除密码信息
                user.setPassword(null);
                
                // 将用户信息存储到会话中
                request.getSession().setAttribute("user", user);

                log.info("用户登录成功：{}", username);
                return user;
            } else {
                log.warn("用户登录失败：用户名或密码错误 - {}", username);
            }
        } catch (Exception e) {
            log.error("用户登录异常：{}", e.getMessage(), e);
        }
        return null;
    }

    /**
     * 根据用户ID获取用户信息
     * 
     * @param userId 用户ID
     * @return User 用户信息（已清除密码），不存在返回null
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public User getUserById(Long userId) {
        try {
            User user = userMapper.selectById(userId);
            if (user != null) {
                user.setPassword(null); // 清除密码信息
            }
            return user;
        } catch (Exception e) {
            log.error("根据用户ID查询用户异常：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据用户名获取用户信息
     * 
     * @param username 用户名
     * @return User 用户信息（已清除密码），不存在返回null
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public User getUserByUsername(String username) {
        try {
            User user = userMapper.selectByUsername(username);
            if (user != null) {
                user.setPassword(null); // 清除密码信息
            }
            return user;
        } catch (Exception e) {
            log.error("根据用户名查询用户异常：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据手机号获取用户信息
     * 
     * @param phone 手机号
     * @return User 用户信息（已清除密码），不存在返回null
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public User getUserByPhone(String phone) {
        try {
            User user = userMapper.selectByPhone(phone);
            if (user != null) {
                user.setPassword(null); // 清除密码信息
            }
            return user;
        } catch (Exception e) {
            log.error("根据手机号查询用户异常：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 根据邮箱获取用户信息
     * 
     * @param email 邮箱地址
     * @return User 用户信息（已清除密码），不存在返回null
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public User getUserByEmail(String email) {
        try {
            User user = userMapper.selectByEmail(email);
            if (user != null) {
                user.setPassword(null); // 清除密码信息
            }
            return user;
        } catch (Exception e) {
            log.error("根据邮箱查询用户异常：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 更新用户信息
     * 
     * @param user 要更新的用户信息
     * @return boolean 更新是否成功
     * @throws Exception 更新过程中可能出现的异常
     */
    @Override
    public boolean updateUser(User user) {
        try {
            int result = userMapper.update(user);
            if (result > 0) {
                log.info("用户信息更新成功：{}", user.getUserId());
                return true;
            }
        } catch (Exception e) {
            log.error("用户信息更新异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 删除用户
     * 
     * @param userId 要删除的用户ID
     * @return boolean 删除是否成功
     * @throws Exception 删除过程中可能出现的异常
     */
    @Override
    public boolean deleteUser(Long userId) {
        try {
            int result = userMapper.deleteById(userId);
            if (result > 0) {
                log.info("用户删除成功：{}", userId);
                return true;
            }
        } catch (Exception e) {
            log.error("用户删除异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 分页查询用户列表
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param user 查询条件
     * @return PageInfo<User> 分页用户列表（已清除密码信息）
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public PageInfo<User> getUserList(int pageNum, int pageSize, User user) {
        try {
            PageHelper.startPage(pageNum, pageSize);
            List<User> users = userMapper.selectByCondition(user);
            
            // 清除密码信息
            users.forEach(u -> u.setPassword(null));
            
            return new PageInfo<>(users);
        } catch (Exception e) {
            log.error("分页查询用户列表异常：{}", e.getMessage(), e);
            return new PageInfo<>();
        }
    }

    /**
     * 获取所有用户
     * 
     * @return List<User> 所有用户列表（已清除密码信息）
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public List<User> getAllUsers() {
        try {
            List<User> users = userMapper.selectAll();
            
            // 清除密码信息
            users.forEach(u -> u.setPassword(null));
            
            return users;
        } catch (Exception e) {
            log.error("查询所有用户异常：{}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 获取用户总数
     * 
     * @return Long 用户总数
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public Long getUserCount() {
        try {
            return userMapper.selectCount();
        } catch (Exception e) {
            log.error("统计用户总数异常：{}", e.getMessage(), e);
            return 0L;
        }
    }

    /**
     * 更新用户最后登录时间
     * 
     * @param userId 用户ID
     * @return boolean 更新是否成功
     * @throws Exception 更新过程中可能出现的异常
     */
    @Override
    public boolean updateLastLoginTime(Long userId) {
        try {
            int result = userMapper.updateLastLoginTime(userId, java.time.LocalDateTime.now());
            return result > 0;
        } catch (Exception e) {
            log.error("更新用户最后登录时间异常：{}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 修改用户密码
     * 
     * @param userId 用户ID
     * @param oldPassword 原密码（明文）
     * @param newPassword 新密码（明文）
     * @return boolean 修改是否成功
     * @throws Exception 修改过程中可能出现的异常
     * @apiNote 需要验证原密码，新密码会进行BCrypt加密
     */
    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        try {
            User user = userMapper.selectById(userId);
            if (user == null) {
                log.warn("修改密码失败：用户不存在 - {}", userId);
                return false;
            }

            if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
                log.warn("修改密码失败：原密码错误 - {}", userId);
                return false;
            }

            String encodedPassword = passwordEncoder.encode(newPassword);
            int result = userMapper.updatePassword(userId, encodedPassword);
            
            if (result > 0) {
                log.info("用户密码修改成功：{}", userId);
                return true;
            }
        } catch (Exception e) {
            log.error("修改密码异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 重置用户密码（管理员功能）
     * 
     * @param userId 用户ID
     * @param newPassword 新密码（明文）
     * @return boolean 重置是否成功
     * @throws Exception 重置过程中可能出现的异常
     * @apiNote 无需验证原密码，新密码会进行BCrypt加密
     */
    @Override
    public boolean resetPassword(Long userId, String newPassword) {
        try {
            String encodedPassword = passwordEncoder.encode(newPassword);
            int result = userMapper.updatePassword(userId, encodedPassword);
            
            if (result > 0) {
                log.info("用户密码重置成功：{}", userId);
                return true;
            }
        } catch (Exception e) {
            log.error("重置密码异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 更新用户状态
     * 
     * @param userId 用户ID
     * @param status 用户状态（0-禁用，1-启用）
     * @return boolean 更新是否成功
     * @throws Exception 更新过程中可能出现的异常
     */
    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        try {
            int result = userMapper.updateStatus(userId, status);
            if (result > 0) {
                log.info("用户状态更新成功：{} - {}", userId, status);
                return true;
            }
        } catch (Exception e) {
            log.error("更新用户状态异常：{}", e.getMessage(), e);
        }
        return false;
    }

    /**
     * 检查用户名是否存在
     * 
     * @param username 用户名
     * @return boolean 是否存在
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public boolean isUsernameExists(String username) {
        try {
            return userMapper.selectByUsername(username) != null;
        } catch (Exception e) {
            log.error("检查用户名是否存在异常：{}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查手机号是否存在
     * 
     * @param phone 手机号
     * @return boolean 是否存在
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public boolean isPhoneExists(String phone) {
        try {
            return userMapper.selectByPhone(phone) != null;
        } catch (Exception e) {
            log.error("检查手机号是否存在异常：{}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 检查邮箱是否存在
     * 
     * @param email 邮箱地址
     * @return boolean 是否存在
     * @throws Exception 查询过程中可能出现的异常
     */
    @Override
    public boolean isEmailExists(String email) {
        try {
            return userMapper.selectByEmail(email) != null;
        } catch (Exception e) {
            log.error("检查邮箱是否存在异常：{}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 通过验证码重置密码
     * 
     * @param email 邮箱地址
     * @param verificationCode 验证码
     * @param newPassword 新密码（明文）
     * @return boolean 重置是否成功
     * @throws Exception 重置过程中可能出现的异常
     */
    @Override
    public boolean resetPasswordByVerificationCode(String email, String verificationCode, String newPassword) {
        try {
            // 验证验证码
            if (!verificationCodeService.verifyCode(email, verificationCode)) {
                log.warn("通过验证码重置密码失败：验证码错误或已过期 - {}", email);
                return false;
            }

            // 根据邮箱查找用户
            User user = userMapper.selectByEmail(email);
            if (user == null) {
                log.warn("通过验证码重置密码失败：用户不存在 - {}", email);
                return false;
            }

            // 加密新密码
            String encodedPassword = passwordEncoder.encode(newPassword);
            
            // 更新密码
            int result = userMapper.updatePassword(user.getUserId(), encodedPassword);
            
            if (result > 0) {
                // 清除验证码
                verificationCodeService.clearCode(email);
                log.info("通过验证码重置密码成功：{}", email);
                return true;
            }
        } catch (Exception e) {
            log.error("通过验证码重置密码异常：{}", e.getMessage(), e);
        }
        return false;
    }
}